package kn.pulldata.config;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import javax.annotation.PreDestroy;
import java.time.Duration;


@Configuration
public class RedisConfig {


    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.password}")
    private String password;
    private LettuceConnectionFactory lettuceConnectionFactoryDb2;

    private LettuceConnectionFactory lettuceConnectionFactoryDb0;


    @PreDestroy
    public void cleanup() {
        if (lettuceConnectionFactoryDb2 != null) {
            lettuceConnectionFactoryDb2.destroy(); // 关闭连接工厂
        }
        if (lettuceConnectionFactoryDb0 != null) {
            lettuceConnectionFactoryDb0.destroy(); // 关闭连接工厂
        }
    }
    @Bean
    public RedisConnectionFactory  redisConnectionFactoryDb2() {

        lettuceConnectionFactoryDb2 =
                createLettuceConnectionFactory(2, host, 6379, password,
                        200, 20, 2000, 60000L, 60000L,120000L);
        //刷新配置
        lettuceConnectionFactoryDb2.afterPropertiesSet();
        //重置连接
        lettuceConnectionFactoryDb2.resetConnection();
        return lettuceConnectionFactoryDb2;
    }

    @Bean
    public RedisTemplate<String, String> redisTemplateDb2() {
        RedisTemplate<String, String> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactoryDb2());
        return template;
    }

    @Bean
    public RedisTemplate<String, String> redisTemplateWithString() {
        RedisTemplate<String, String> template = new RedisTemplate<>();
        lettuceConnectionFactoryDb0 =
                createLettuceConnectionFactory(0, host, 6379, password,
                        10, 5, 500, 60000L, 60000L,60000L);

        //刷新配置

        lettuceConnectionFactoryDb0.afterPropertiesSet();
        //重置连接
        lettuceConnectionFactoryDb0.resetConnection();
        template.setConnectionFactory(lettuceConnectionFactoryDb0);

        // 使用 StringRedisSerializer 序列化 key 和 value
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        // 设置 key 和 value 的序列化方式为 StringRedisSerializer
        template.setKeySerializer(stringRedisSerializer);
        template.setValueSerializer(stringRedisSerializer);

        // 设置 Hash key 和 Hash value 的序列化方式为 StringRedisSerializer
        template.setHashKeySerializer(stringRedisSerializer);
        template.setHashValueSerializer(stringRedisSerializer);

        template.afterPropertiesSet();
        return template;
    }


    private  LettuceConnectionFactory createLettuceConnectionFactory(
            int dbIndex, String hostName, int port, String password,
            int maxIdle,int minIdle,int maxActive,
            Long maxWait, Long timeOut,Long shutdownTimeOut){

        //redis配置
        RedisConfiguration redisConfiguration = new
                RedisStandaloneConfiguration(hostName,port);
        ((RedisStandaloneConfiguration) redisConfiguration).setDatabase(dbIndex);
        ((RedisStandaloneConfiguration) redisConfiguration).setPassword(password);

        //连接池配置
        GenericObjectPoolConfig genericObjectPoolConfig =
                new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxIdle(maxIdle);
        genericObjectPoolConfig.setMinIdle(minIdle);
        genericObjectPoolConfig.setMaxTotal(maxActive);
        genericObjectPoolConfig.setMaxWaitMillis(maxWait);

        //redis客户端配置
        LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder
                builder =  LettucePoolingClientConfiguration.builder().
                commandTimeout(Duration.ofMillis(timeOut));

        builder.shutdownTimeout(Duration.ofMillis(shutdownTimeOut));
        builder.poolConfig(genericObjectPoolConfig);
        LettuceClientConfiguration lettuceClientConfiguration = builder.build();

        //根据配置和客户端配置创建连接
        LettuceConnectionFactory lettuceConnectionFactory = new
                LettuceConnectionFactory(redisConfiguration,lettuceClientConfiguration);
        lettuceConnectionFactory.afterPropertiesSet();

        return lettuceConnectionFactory;
    }
}
